package club.pinea.client;

import club.pinea.model.User;
import club.pinea.proto.BasicProto;
import club.pinea.proto.UserProto;
import club.pinea.session.CallbackContainer;
import club.pinea.session.ClientPlayer;
import club.pinea.session.MessageSend;
import club.pinea.util.PrintUtil;
import club.pinea.util.ResUtil;
import com.alibaba.fastjson.JSONObject;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

import static club.pinea.util.PrintUtil.*;

@Component
@ChannelHandler.Sharable
public class LoginClientHandler extends SimpleChannelInboundHandler<BasicProto.BaseMessage> {

    @Autowired
    private GameClient gameClient;

    /**
     * 登陆操作
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        //首页操作
        ClientPlayer.setContext(ctx);
        homeOperation();
    }

    /**
     * @description: 首页操作
     * @author: 华上进
     * @createTime: 2021/7/2 15:28
     */
    private void homeOperation() {
        List<String> tipMessageList = Arrays.asList("请选择操作：", "1、登陆（我已有账号直接登录~）", "2、注册");
        Integer homeData = nextScanInt(tipMessageList, "请输入正确操作！");
        // 初始化 arrayList
        tipMessageList = new ArrayList<>();
        switch (homeData) {
            case 1:
                // 调用登录
                login(tipMessageList);
                break;
            case 2:
                // 创建账户逻辑请求
                regUser(tipMessageList);
                break;
        }
    }

    /**
     * @description: 创建用户账号
     * @author: 华上进
     * @createTime: 2021/7/2 15:11
     */
    private void regUser(List<String> tipMessageList) {
        User regData = printRegForm();
        UserProto.RegisterRequest registerRequest = UserProto.RegisterRequest.newBuilder()
                .setName(regData.getUsername())
                .setPass(regData.getPassword())
                .setBeInvited(regData.getBeInvited())
                .build();
        MessageSend.sendToUser(registerRequest, ClientPlayer.getContext(), (registerRequestBaseMessage) -> {
            System.out.println(registerRequestBaseMessage);
            UserProto.RegisterResponse registerResponse = UserProto.RegisterResponse.parseFrom(registerRequestBaseMessage.getBody());
            if (ResUtil.isSuccess(registerResponse.getRes())) {
                // 注册成功
                System.out.println("账号：" + regData.getUsername() + " 注册成功,跳转登录页面进行登陆。");
                login(tipMessageList);
            } else {
                // 注册失败
                System.out.println(registerResponse.getRes().getDesc());
                Integer switchScanner = nextScanInt(Arrays.asList("-----创建失败！-----", "-----请选择如下操作？-----", "1、重新创建", "2、已有账号登陆", "3、退出系统"), "输入有误，请重新输入");
                switch (switchScanner) {
                    case 1:
                        regUser(tipMessageList);
                        break;
                    case 2:
                        // 已有账号登陆
                        login(tipMessageList);
                        break;
                    case 3:
                        // 退出系统
                        System.out.println("已成功退出系统。");
                        break;
                    case -1:
                        System.out.println("===================操作有误,跳转到首页=======================");
                        homeOperation();
                        break;
                }
            }
        });
    }


    /**
     * @description: 登录操作逻辑
     * @author: 华上进
     * @createTime: 2021/7/2 14:52
     */
    private void login(List<String> tipMessageList) {
        // 控制台输入 用户名 密码登陆
        User userRequest = PrintUtil.printLoginForm();

        // 控制台输入的值赋值到对象
        UserProto.LoginRequest loginRequest = UserProto.LoginRequest.newBuilder()
                .setName(userRequest.getUsername())
                .setPass(userRequest.getPassword())
                .build();
        // 数据发送到登陆handler走登陆逻辑
        MessageSend.sendToUser(loginRequest, ClientPlayer.getContext(), (baseMessage) -> {
            // 回调拿到登陆后的response 实体结果集
            UserProto.LoginResponse response = UserProto.LoginResponse.parseFrom(baseMessage.getBody());
            // 判断若为成功
            if (ResUtil.isSuccess(response.getRes())) {
                // 存入 客户端保存用户信息对象
                ClientPlayer.setInfo(response);
                loginSuccess(tipMessageList, userRequest);


            } else {
                //登录失败
                System.out.println("---------------" + response.getRes().getDesc() + "------------------");
                System.out.println("请选择重新登陆");
                Integer rollBackHomeIsTrue = nextScanInt("输入 -1 返回首页，其他继续进行登陆。", "输入有误，请重新输入");
                if (rollBackHomeIsTrue == -1) {
                    homeOperation();
                } else {
                    // 已有账号登陆
                    login(tipMessageList);
                }


            }
        });
    }

    /**
     * @description: 登陆成功
     * @author: 华上进
     * @createTime: 2021/7/2 16:28
     */
    private void loginSuccess(List<String> tipMessageList, User userRequest) {
        // 登陆成功选择操作  1、游戏  2、创建用户handler处理类 3、修改密码
        tipMessageList = new ArrayList<>();
        Collections.addAll(tipMessageList,
                "*******************欢迎您，" + userRequest.getUsername() + " 超级VIP用户********************",
                "请选择如下操作：",
                "1、==葫芦游戏机==",
                "2、==查看账户信息==",
                "3、==修改密码==",
                "*****************************************************************************************");
        Integer switchScanner = nextScanInt(tipMessageList, "输入有误，请重新输入");
        switch (switchScanner) {
            case 1:
                //启动游戏 GameClient run
                new Thread(gameClient).start();
                break;
            case 2:
                // 查看账户信息 todo 这里暂时弄个登陆时候查询的数据
                System.out.println("************当前金额****************");
                System.out.println("**" + ClientPlayer.getUserInfo().getMoney() + "￥ **");
                System.out.println("****************************");
                Integer rollbackData = nextScanInt("输入任意数字返回 上一层。", "输入有误，请重新输入");
                if (rollbackData != null) {
                    loginSuccess(tipMessageList, userRequest);
                }
                break;
            case 3:
                // 修改密码 map 只会返回一条数据
                updatePassword(tipMessageList, userRequest);
                break;
        }
    }

    /**
     * @description: 修改密码
     * @author: 华上进
     * @createTime: 2021/7/2 16:27
     */
    private void updatePassword(List<String> tipMessageList, User userRequest) {
        Map<String, String> map = updatePasswordReturn();
        UserProto.UpdatePwdRequest updatePwdRequest = UserProto.UpdatePwdRequest.newBuilder()
                .setName(userRequest.getUsername())
                .setOldPass(map.get("oldPassword"))
                .setNewPass(map.get("newPassword"))
                .build();
        MessageSend.sendToUser(updatePwdRequest, ClientPlayer.getContext(), (baseMessage) -> {
            UserProto.UpdatePwdResponse updatePwdResponse = UserProto.UpdatePwdResponse.parseFrom(baseMessage.getBody());
            if (ResUtil.isSuccess(updatePwdResponse.getRes())) {
                System.out.println(updatePwdResponse.getRes().getDesc() + " 跳转到欢迎页面");
                loginSuccess(tipMessageList, userRequest);
            } else {
                System.out.println(updatePwdResponse.getRes().getDesc() + "，请重新修改密码！");
                Integer rollBackHomeIsTrue = nextScanInt("输入 -1 返回欢迎页面，其他继续修改密码。", "输入有误，请重新输入");
                if (rollBackHomeIsTrue == -1) {
                    loginSuccess(tipMessageList, userRequest);
                } else {
                    updatePassword(tipMessageList, userRequest);
                }
            }

        });
    }

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, BasicProto.BaseMessage baseMessage) throws Exception {
//        System.out.println("接收到服务端返回消息: " + baseMessage);
        CallbackContainer.doCallback(baseMessage.getOrder(), baseMessage);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {

        cause.printStackTrace();
        System.out.println("出错了");
        ctx.close();
    }


    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            if (((IdleStateEvent) evt).state() == IdleState.WRITER_IDLE) {
                JSONObject obj = new JSONObject();
                obj.put("order", "h");
                ctx.writeAndFlush(obj.toString());
                System.out.println("club.pinea.client-heart");
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }

}
